/** Provides classes for detecting generated code. */

private import codeql.ruby.AST
private import codeql.ruby.ast.internal.TreeSitter

/** A source file that contains generated code. */
abstract class GeneratedCodeFile extends RubyFile { }

/** A file continuing comments suggesting it contains generated code. */
class GeneratedCommentFile extends GeneratedCodeFile {
  GeneratedCommentFile() { this = any(GeneratedCodeComment c).getLocation().getFile() }
}

/** A comment line that indicates generated code. */
abstract class GeneratedCodeComment extends Ruby::Comment { }

/**
 * A generic comment line that suggests that the file is generated.
 */
class GenericGeneratedCodeComment extends GeneratedCodeComment {
  GenericGeneratedCodeComment() {
    exists(string line, string entity, string was, string automatically | line = this.getValue() |
      entity = "file|class|art[ei]fact|module|script" and
      was = "was|is|has been" and
      automatically = "automatically |mechanically |auto[- ]?" and
      line.regexpMatch("(?i).*\\bThis (" + entity + ") (" + was + ") (" + automatically +
          ")?generated\\b.*")
    )
  }
}

/** A comment warning against modifications. */
class DontModifyMarkerComment extends GeneratedCodeComment {
  DontModifyMarkerComment() {
    exists(string line | line = this.getValue() |
      line.regexpMatch("(?i).*\\bGenerated by\\b.*\\bDo not edit\\b.*") or
      line.regexpMatch("(?i).*\\bAny modifications to this file will be lost\\b.*")
    )
  }
}

/** Holds if `file` looks like it contains generated code. */
predicate isGeneratedCode(GeneratedCodeFile file) { any() }
